package common

import (
	"log"
	"runtime"
	"time"
)

var (
	memoryThreshold    = 80   // 内存使用率阈值（百分比）
	goroutineThreshold = 1000 // goroutine 数量阈值
)

// StartMemoryMonitor 启动内存监控
func StartMemoryMonitor(interval time.Duration) {
	go func() {
		ticker := time.NewTicker(interval)
		defer ticker.Stop()

		for range ticker.C {
			var m runtime.MemStats
			runtime.ReadMemStats(&m)

			// 计算内存使用率
			memoryUsage := float64(m.Alloc) / float64(m.Sys) * 100

			// 记录内存使用情况
			log.Printf("Memory Usage: %.2f%% (Alloc: %v MiB, Sys: %v MiB, NumGC: %v)",
				memoryUsage,
				m.Alloc/1024/1024,
				m.Sys/1024/1024,
				m.NumGC,
			)

			// 如果内存使用率超过阈值，触发 GC
			if memoryUsage > float64(memoryThreshold) {
				log.Printf("Memory usage exceeds threshold (%.2f%%), triggering GC", memoryUsage)
				runtime.GC()
			}
		}
	}()
}

// MonitorGoroutines 监控 goroutine 数量
func MonitorGoroutines(threshold int) {
	goroutineThreshold = threshold
	go func() {
		ticker := time.NewTicker(30 * time.Second)
		defer ticker.Stop()

		for range ticker.C {
			count := runtime.NumGoroutine()
			log.Printf("Current goroutine count: %d", count)

			if count > goroutineThreshold {
				log.Printf("Warning: High number of goroutines (%d)", count)
				// 这里可以添加告警通知等逻辑
			}
		}
	}()
}

// SetMemoryThreshold 设置内存使用率阈值
func SetMemoryThreshold(threshold int) {
	if threshold > 0 && threshold <= 100 {
		memoryThreshold = threshold
	}
}

// GetMemoryStats 获取当前内存统计信息
func GetMemoryStats() (alloc, sys uint64, numGC uint32) {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	return m.Alloc, m.Sys, m.NumGC
}

// 内存使用优化建议：
// 1. 使用context控制goroutine生命周期
// 2. 及时关闭文件、数据库连接等资源
// 3. 避免在循环中创建大量临时对象
// 4. 使用对象池复用对象
// 5. 避免在闭包中持有大对象的引用
// 6. 使用defer确保资源释放
// 7. 定期检查goroutine数量
// 8. 使用pprof进行性能分析
